#include <stdio.h>
#include <stdlib.h>
#include "trie.c"
#include <string.h>
#include <mpi.h>
#ifdef _OPENMP
#include <omp.h>
#define NTHREADS 4
#endif

#define WORD_SIZE 6 //fgets ira ler ate no maximo 5 caracteres

char charRand()
{
	return (char)((lrand48()%26) + 97);
}

void removeEOL (char* str)
{
	int i;
	for (i = 0 ; i < strlen(str) ; i++)
	{
		if (str[i] == '\n')
		{
			str[i] = '\0';
		}
	}	
}

int outracoisa (void)
{
	long WORD_NUM = 3165769; //numero de palavras que existem no arquivo palavrasFiltrado.txt
	Trie* shards1;
	Trie* shards2;
	Trie* shards3;
	Trie* shards4;
	Trie* shards5;
	shards1 = trie_new();
	shards2 = trie_new();
	shards3 = trie_new();
	shards4 = trie_new();
	shards5 = trie_new();
	void* valor = (void*)1;
	char** dictionary;
	dictionary = (char**) malloc (WORD_NUM * sizeof(char*));
	char aux[100];
	int num = 0;
	FILE* fpin;
	long num1, num2, num3, num4, num5;
	num1 = num2 = num3 = num4 = num5 = 0;
	int rank, rc;
	
	if ((fpin = fopen("palavrasFiltrado.txt", "r")) == NULL)
	{
		printf("Houve um erro ao abrir o arquivo\n");
	}
	
	//Carrega todas as palavras no dicionario global
	long n = 0;
	while (1)
	{
		if (fgets(aux, 100, fpin) == NULL)
		{
			if (feof(fpin))
			{
				break;
			}
			else
			{
				printf("Erro de leitura do arquivo\n");
				return -1;
			}
		}
		dictionary[n] = strdup(aux);
		n++;
	}
	
	fseek(fpin, 0, SEEK_SET);
	
	//Carrega os pedacos de palavra na estrutura Trie
	while (1)
	{
		if (fgets(aux, WORD_SIZE, fpin) == NULL)
		{
			if (feof(fpin))
			{
				break;
			}
			else
			{
				printf("Erro de leitura do arquivo\n");
				return -1;
			}
		}
		
		removeEOL(aux);
		
		//Carrega fragmentos em cada uma das estruturas Trie, de acordo com seu tamanho, e apenas se não existirem anteriormente
		if (strlen(aux) == 1)
		{
			if (!trie_lookup(shards1, aux))
			{
				trie_insert(shards1, aux, valor);
				//printf("%s\n", aux);
				num1++;
			}
		} 
		else if (strlen(aux) == 2) 
		{
			if (!trie_lookup(shards2, aux))
			{
				trie_insert(shards2, aux, valor);
				num2++;
			}
		}
		else if (strlen(aux) == 3) 
		{
			if (!trie_lookup(shards3, aux))
			{
				trie_insert(shards3, aux, valor);
				num3++;
			}
		}
		else if (strlen(aux) == 4) 
		{
			if (!trie_lookup(shards4, aux))
			{
				trie_insert(shards4, aux, valor);
				num4++;
			}
		}
		else if (strlen(aux) == 5) 
		{
			if (!trie_lookup(shards5, aux))
			{
				trie_insert(shards5, aux, valor);
				num5++;
			}
		}
	}
	
	printf("%ld\n%ld\n%ld\n%ld\n%ld\n\n", num1, num2, num3, num4, num5);
	char t[2];
	srand48(time(NULL));
	
	printf("%d\n", trie_lookup(shards1, "a")); 
	
	t[0] = 'a';
	t[1] = '\n';
	t[2] = '\0';
	
	removeEOL(t);
	
	while (1)
	{
		//printf("%d\n", trie_lookup(shards1, t));
		if (trie_lookup(shards1, t) == 1)
		{
			//printf("%s\n", t);
		}
	}
}

int main(int argc, char *argv[])
{
	int rank;
	int rc;
	
	rc = MPI_Init(&argc, &argv);
	if (rc == MPI_SUCCESS)
	{
		//Obtem ID do processo na variável rank	
		MPI_Comm_rank(MPI_COMM_WORLD, &rank);
		
		//Pega numero de processos que irao rodar para fazer a distribuicao de tarefas
		int nProc;
		MPI_Comm_size(MPI_COMM_WORLD, &nProc);
		
		if (rank == 0)
		{
			MPI_Status status;
			while (1)
			{
				char msg[5];
				MPI_Recv(msg, 5, MPI_CHAR, MPI_ANY_SOURCE, 4, MPI_COMM_WORLD, &status);
				printf("%s\n",msg);
			}
		}
		
		if (rank == 1)
		{
			while (1)
			{
				MPI_Request handle;
				MPI_Isend("test", 5, MPI_CHAR, 0, 4, MPI_COMM_WORLD, &handle);
			}
		}
	}
		

	
	/*int flag = 1; 
	int flag2 = 0;
	int teste[3] = {-1,-1,-1};
	#pragma omp parallel num_threads(4)
	{
		if (omp_get_thread_num() == 0)
		{
			while (flag)
			{
			}
			printf("Thread 0 acabou\n");
		}
		else
		{
				teste[(omp_get_thread_num() - 1)] = omp_get_thread_num();
				#pragma omp critical
				{
					flag2++;
				}
				//printf("%d\n", omp_get_thread_num());
				
				while(flag2!=3)
				{}
				
				#pragma omp single
				{
					printf("%d, %d, %d\n", teste[0], teste[1], teste[2]);
					flag = 0;
				}
			
		}
	}
	printf("Saiu de tudo\n");*/
	return 0;
}